package com.duowan.cms.parser.util;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import com.duowan.cms.common.cache.CacheHolder;
import com.duowan.cms.common.exception.BaseCheckedException;
import com.duowan.cms.common.util.DateUtil;
import com.duowan.cms.common.util.JsonUtil;
import com.duowan.cms.common.util.MD5;
import com.duowan.cms.common.util.PathUtil;
import com.duowan.cms.common.util.StringUtil;
import com.duowan.cms.core.rmi.client.article.Article4TagListRemoteService;
import com.duowan.cms.core.rmi.client.article.ArticleRemoteService;
import com.duowan.cms.core.rmi.client.channel.ChannelRemoteService;
import com.duowan.cms.core.rmi.client.gametest.GameTestRemoteService;
import com.duowan.cms.core.rmi.client.tag.TagRemoteService;
import com.duowan.cms.dto.article.Article4TagListInfo;
import com.duowan.cms.dto.article.Article4TagListSearchCriteria;
import com.duowan.cms.dto.article.Article4TagListSearchCriteria.Article4TagListOrderBy;
import com.duowan.cms.dto.article.ArticleInfo;
import com.duowan.cms.dto.channel.ChannelInfo;
import com.duowan.cms.dto.comment.CommentInfo;
import com.duowan.cms.dto.gametest.GameTestInfo;
import com.duowan.cms.dto.gametest.GameTestSearchCriteria;
import com.duowan.cms.dto.gametest.GameTestSearchCriteria.GameTestOrderBy;
import com.duowan.cms.dto.tag.TagInfo;
import com.duowan.cms.intf.comment3.Comment3RemoteService;
import com.duowan.cms.intf.duowanvote.DuowanVoteRemoteService;
import com.duowan.cms.intf.duowanvote.DuowanVoteSearchCriteria;
import com.duowan.cms.intf.fahao.FahaoInfo;
import com.duowan.cms.intf.fahao.FahaoRemoteService;
import com.duowan.cms.intf.fahao.FahaoRequest;
import com.duowan.cms.intf.piclib.PicLibRemoteService;
import com.duowan.cms.intf.piclib.TujiInfo;
import com.duowan.cms.intf.piclib.TujiRequest;

@Service("templateDataService")
@Scope("prototype")
public class TemplateDataServiceImpl implements TemplateDataService {

    private ChannelInfo channelInfo = null;

    @Autowired
    private ArticleRemoteService articleRemoteService;

    @Autowired
    private Article4TagListRemoteService article4TagListRemoteService;

    @Autowired
    private ChannelRemoteService channelRemoteService;

    @Autowired
    private TagRemoteService tagRemoteService;

    @Autowired
    private FahaoRemoteService fahaoRemoteService;

    @Autowired
    private DuowanVoteRemoteService duowanVoteRemoteService;

    @Autowired
    private PicLibRemoteService picLibRemoteService;
    
    @Autowired
    private GameTestRemoteService gameTestRemoteService;
    
    @Autowired
    private Comment3RemoteService comment3RemoteService;
    
    /**
     * 缓存持有者
     */
    @Autowired
    protected CacheHolder cacheHolder;
    
    // ----文章相关 begin----
    private String getChannelIdByName(String cname) {
        ChannelInfo channelInfo = getChannelInfoByName(cname);
        if (null != channelInfo)
            return channelInfo.getId();
        return null;
    }

    private boolean isLegalChannelId(String channelId) {
        if (StringUtil.isEmpty(channelId) || channelId.indexOf(",") != -1 || channelId.indexOf(" ") != -1)
            return false;
        return true;
    }

    private ChannelInfo getChannelInfoByName(String channelName) {
        if (StringUtil.isEmpty(channelName))
            return null;
        return channelRemoteService.getByName(channelName);
    }

    private List<Article4TagListInfo> getCommonList(String channelId, String tag, int powerfrom, int powerto, String ispic, int start, int len) {

        if (!isLegalChannelId(channelId)) {
            logger.warn("channelId : " + channelId + " is not legal!!");
            return new ArrayList<Article4TagListInfo>();
        }
        Article4TagListSearchCriteria searchCriteria = new Article4TagListSearchCriteria();
        searchCriteria.setChannelId(channelId);
        searchCriteria.addTags(tag);
        searchCriteria.setPowerFrom(powerfrom >= 0 ? powerfrom : null);
        searchCriteria.setPowerTo(powerto > 0 ? powerto : null);
        searchCriteria.setIsHeadPic(ispic);
        searchCriteria.addOrderBy(Article4TagListOrderBy.DAY_NUM_DESC).addOrderBy(Article4TagListOrderBy.POWER_DESC).addOrderBy(Article4TagListOrderBy.POST_TIME_DESC);; 
        //TODO  优化算法
        int pageNo = start / len + 1;
        int mod = start % len;
        
        searchCriteria.setPageNo(pageNo);
        searchCriteria.setPageSize(len);
        List<Article4TagListInfo> list = article4TagListRemoteService.listSearch(searchCriteria); 
        if(mod == 0 || null == list || list.isEmpty()){//不跨页
            return list;
        }else{//跨页 
            searchCriteria.setPageNo(pageNo + 1);
            List<Article4TagListInfo> list2 = article4TagListRemoteService.listSearch(searchCriteria); 
            List<Article4TagListInfo> listAll = new ArrayList<Article4TagListInfo>();
            //添加第一页数据
            for(int i = 0; i < list.size(); i++){
                if(i >= mod)
                    listAll.add(list.get(i));
            }
            //添加第二页数据
            for(int i = 0; i < mod && i < list2.size(); i ++){
                listAll.add(list2.get(i));
            }
            return listAll;
        }
    }

    @Override
    public List<Article4TagListInfo> getListOther(String cname, String tag, int powerfrom, int powerto, int start, int len) {
        return getList(tag, getChannelIdByName(cname), powerfrom, powerto, start, len);
    }

    @Override
    public List<Article4TagListInfo> getList(String tag, int powerfrom, int powerto, int start, int len) {
        return getList(tag, channelInfo.getId(), powerfrom, powerto, start, len);
    }

    @Override
    public List<Article4TagListInfo> getList(String tag, String cid, int powerfrom, int powerto, int start, int len) {
        return getCommonList(cid, tag, powerfrom, powerto, null, start, len);
    }

    @Override
    public List<Article4TagListInfo> getListOther(String cname, String tag, int powerfrom, int powerto, int len) {
        return getListOther(cname, tag, powerfrom, powerto, 0, len);
    }

    @Override
    public List<Article4TagListInfo> getList(String tag, int powerfrom, int powerto, int len) {
        return getList(tag, powerfrom, powerto, 0, len);
    }

    @Override
    public List<Article4TagListInfo> getListOther(String cname, String tag, int start, int len) {
        return getListOther(cname, tag, 0, 0, start, len);
    }

    @Override
    public List<Article4TagListInfo> getList(String tag, int start, int len) {
        return getList(tag, 0, 0, start, len);
    }

    @Override
    public List<Article4TagListInfo> getListOther(String cname, String tag, int len) {
        return getListOther(cname, tag, 0, len);
    }

    @Override
    public List<Article4TagListInfo> getList(String tag, int len) {
        return getList(tag, 0, len);
    }

    @Override
    public List<Article4TagListInfo> getPicList(String tag, int powerfrom, int powerto, int start, int len) {
        return getCommonList(channelInfo.getId(), tag, powerfrom, powerto, "yes", start, len);
    }

    @Override
    public List<Article4TagListInfo> getPicList(String tag, int powerfrom, int powerto, int len) {
        return getPicList(tag, powerfrom, powerto, 0, len);
    }

    @Override
    public List<Article4TagListInfo> getPicList(String tag, int start, int len) {
        return getPicList(tag, 0, 0, start, len);
    }

    @Override
    public List<Article4TagListInfo> getPicList(String tag, int len) {
        return getPicList(tag, 0, len);
    }

    @Override
    public List<Article4TagListInfo> getPicListOther(String cname, String tag, int powerfrom, int powerto, int start, int len) {
        return getCommonList(getChannelIdByName(cname), tag, powerfrom, powerto, "yes", start, len);
    }

    @Override
    public List<Article4TagListInfo> getPicListOther(String cname, String tag, int powerfrom, int powerto, int len) {
        return getPicListOther(cname, tag, powerfrom, powerto, 0, len);
    }

    @Override
    public List<Article4TagListInfo> getPicListOther(String cname, String tag, int start, int len) {
        return getPicListOther(cname, tag, 0, 0, start, len);
    }

    @Override
    public List<Article4TagListInfo> getPicListOther(String cname, String tag, int len) {
        return getPicListOther(cname, tag, 0, len);
    }

    @Override
    public List<Article4TagListInfo> getRelate(String tags, int powerfrom, int powerto, int len) {
        // TODO YZQ 待优化 !!根据tags查询相关文章,与旧版有差别!
        if (StringUtil.isEmpty(tags))
            return new ArrayList<Article4TagListInfo>();
        String[] tagArray = tags.split(",");
        if (tagArray.length == 1)
            return getList(tagArray[0], powerfrom, powerto, len);
        
        Map<String, Article4TagListInfo> map = new HashMap<String, Article4TagListInfo>();
        for(String tag : tagArray){
            List<Article4TagListInfo> list = getList(tag, powerfrom, powerto, len);
            for(Article4TagListInfo a : list){
                Article4TagListInfo a_inMap = map.get(a.getId() + "");
                if(null == a_inMap){
                    map.put(a.getId() + "", a);
                }else if(compareTwoArticle4TagListInfo(a_inMap, a) > 0){
                    map.put(a.getId() + "", a);
                }
            }
        }
        // 将map中前len个对象放入返回列表中
        List<Article4TagListInfo> list = new ArrayList<Article4TagListInfo>(map.values());
        Collections.sort(list, new Comparator<Article4TagListInfo>(){
            @Override
            public int compare(Article4TagListInfo o1, Article4TagListInfo o2) {
                return compareTwoArticle4TagListInfo(o1, o2);
            }
        });
        
        if(len > list.size()){
            return list;
        }else{
            return list.subList(0, len);
        }
    }
    
    private int compareTwoArticle4TagListInfo(Article4TagListInfo o1, Article4TagListInfo o2) {
        
        if(o1.getDayNum() > o2.getDayNum()){
            return -1;
        }else if(o1.getDayNum() < o2.getDayNum()){
            return 1;
        }else{
            if(o1.getPower() > o2.getPower()){
                return -1;
            }else if(o1.getPower() < o2.getPower()){
                return 1;
            }else{
                if(o1.getId() > o2.getId()){
                    return -1;
                }else{
                    return 1;
                }
            }
        }
    }

    @Override
    public List<Article4TagListInfo> getRelate(String tags, int len) {
        return getRelate(tags, 0, 0, len);
    }

    @Override
    public ArticleInfo getArticleInfo(String articleId) {
        return articleRemoteService.getByChannelIdAndArticleId(channelInfo.getId(), Long.parseLong(articleId));
    }

    @Override
    public ArticleInfo getArticleInfo(String articleId, String channelId) {
        return articleRemoteService.getByChannelIdAndArticleId(channelId, Long.parseLong(articleId));
    }

    // ----文章相关 end----

    // ----游戏测试表：gametestinfo相关 begin----
    @Override
    public List<GameTestInfo> getGameTestList(String starttime, String endtime, int ctype) {
        /*GameTestSearchCriteria searchCriteria = new GameTestSearchCriteria();
        searchCriteria.setAbroadNot("on");
        searchCriteria.setTimeStart(starttime);
        searchCriteria.setTimeEnd(endtime);
        searchCriteria.setCtype(ctype);
        searchCriteria.addOrderBy(GameTestOrderBy.TIME_DESC).addOrderBy(GameTestOrderBy.POWER_DESC);
        searchCriteria.setPageSize(null);
        
        return gameTestRemoteService.listSearch(searchCriteria);*/
        Map<String, String> map = new HashMap<String, String>();
        map.put("abroadNot", "on");
        map.put("timeStart", starttime);
        map.put("timeEnd", endtime);
        map.put("order1", "time");
        map.put("order1Type", "desc");
        map.put("order2", "weights");
        map.put("order2Type", "desc");
        return fahaoRemoteService.listSearchGameTestInfo(map);
    }

    @Override
    public List<GameTestInfo> getGameTestListRest(String starttime, String endtime, int ctype, int len) {
        /*GameTestSearchCriteria searchCriteria = new GameTestSearchCriteria();
        searchCriteria.setAbroadNot("on");
        searchCriteria.setTimeStart(starttime);
        searchCriteria.setTimeEnd(endtime);
        searchCriteria.setCtype(ctype);
        searchCriteria.addOrderBy(GameTestOrderBy.TIME_ASC).addOrderBy(GameTestOrderBy.POWER_DESC);
        searchCriteria.setPageSize(len);
        
        List<GameTestInfo> list = gameTestRemoteService.listSearch(searchCriteria);
        return list;*/
        Map<String, String> map = new HashMap<String, String>();
        map.put("abroadNot", "on");
        map.put("timeStart", starttime);
        map.put("timeEnd", endtime);
        map.put("order1", "time");
        map.put("order1Type", "asc");
        map.put("order2", "weights");
        map.put("order2Type", "desc");
        map.put("length", len + "");
        return fahaoRemoteService.listSearchGameTestInfo(map);
        
    }

    @Override
    public List<GameTestInfo> getGameTestList(String starttime, String endtime, int ctype, int len) {
        /*GameTestSearchCriteria searchCriteria = new GameTestSearchCriteria();
        searchCriteria.setAbroadNot("on");
        searchCriteria.setTimeStart(starttime);
        searchCriteria.setTimeEnd(endtime);
        searchCriteria.setCtype(ctype);
        searchCriteria.addOrderBy(GameTestOrderBy.TIME_DESC).addOrderBy(GameTestOrderBy.POWER_DESC);
        searchCriteria.setPageSize(len);
        
        return gameTestRemoteService.listSearch(searchCriteria);*/
        
        Map<String, String> map = new HashMap<String, String>();
        map.put("abroadNot", "on");
        map.put("timeStart", starttime);
        map.put("timeEnd", endtime);
        map.put("order1", "time");
        map.put("order1Type", "desc");
        map.put("order2", "weights");
        map.put("order2Type", "desc");
        map.put("length", len + "");
        return fahaoRemoteService.listSearchGameTestInfo(map);
        
    }

    @Override
    public List<GameTestInfo> getGameTestListAsc(String starttime, String endtime, int ctype, int len) {
        /*GameTestSearchCriteria searchCriteria = new GameTestSearchCriteria();
        searchCriteria.setAbroadNot("on");
        searchCriteria.setTimeStart(starttime);
        searchCriteria.setTimeEnd(endtime);
        searchCriteria.setCtype(ctype);
        searchCriteria.addOrderBy(GameTestOrderBy.TIME_ASC).addOrderBy(GameTestOrderBy.POWER_DESC);
        searchCriteria.setPageSize(len);
        
        return gameTestRemoteService.listSearch(searchCriteria);*/
        
        Map<String, String> map = new HashMap<String, String>();
        map.put("abroadNot", "on");
        map.put("timeStart", starttime);
        map.put("timeEnd", endtime);
        map.put("order1", "time");
        map.put("order1Type", "asc");
        map.put("order2", "weights");
        map.put("order2Type", "desc");
        map.put("length", len + "");
        return fahaoRemoteService.listSearchGameTestInfo(map);
    }

    @Override
    public List<GameTestInfo> getGameTestListAsc2(String starttime, String endtime, int ctype, int len) {
        /*GameTestSearchCriteria searchCriteria = new GameTestSearchCriteria();
        searchCriteria.setAbroadNot("on");
        searchCriteria.setTimeStart(starttime);
        searchCriteria.setTimeEnd(endtime);
        searchCriteria.setCtype(ctype);
        searchCriteria.addOrderBy(GameTestOrderBy.TIME_ASC).addOrderBy(GameTestOrderBy.POWER_DESC).addOrderBy(GameTestOrderBy.ID_DESC);
        searchCriteria.setPageSize(len);
        
        return gameTestRemoteService.listSearch(searchCriteria);*/
        
        Map<String, String> map = new HashMap<String, String>();
        map.put("abroadNot", "on");
        map.put("timeStart", starttime);
        map.put("timeEnd", endtime);
        map.put("order1", "time");
        map.put("order1Type", "asc");
        map.put("order2", "weights");
        map.put("order2Type", "desc");
        map.put("order3", "gameTestId");
        map.put("order3Type", "desc");
        map.put("length", len + "");
        return fahaoRemoteService.listSearchGameTestInfo(map);
    }

    @Override
    public List<GameTestInfo> getGameTestByPower(int powerfrom, int powerto, int ctype) {
        /*GameTestSearchCriteria searchCriteria = new GameTestSearchCriteria();
        searchCriteria.setCtype(ctype);
        searchCriteria.setPowerFrom(powerfrom);
        searchCriteria.setPowerTo(powerto);
        searchCriteria.addOrderBy(GameTestOrderBy.POWER_DESC);
        
        return gameTestRemoteService.listSearch(searchCriteria);*/
        Map<String, String> map = new HashMap<String, String>();
        map.put("weightsFrom", powerfrom + "");
        map.put("weightsTo", powerto + "");
        map.put("order1", "weights");
        map.put("order1Type", "desc");
        return fahaoRemoteService.listSearchGameTestInfo(map);
    }

    @Override
    public List<GameTestInfo> getGameTestByIndex(String starttime, String endtime) {
        /*GameTestSearchCriteria searchCriteria = new GameTestSearchCriteria();
        searchCriteria.setIndexCheck("on");
        searchCriteria.setTimeStart(starttime);
        searchCriteria.setTimeEnd(endtime);
        searchCriteria.setCtype(1);
        searchCriteria.addOrderBy(GameTestOrderBy.TIME_ASC).addOrderBy(GameTestOrderBy.POWER_DESC);
        
        return gameTestRemoteService.listSearch(searchCriteria);*/
        Map<String, String> map = new HashMap<String, String>();
        map.put("checkIndex", "on");
        map.put("timeStart", starttime);
        map.put("timeEnd", endtime);
        map.put("order1", "time");
        map.put("order1Type", "asc");
        map.put("order2", "weights");
        map.put("order2Type", "desc");
        return fahaoRemoteService.listSearchGameTestInfo(map);
    }

    @Override
    public List<GameTestInfo> getGameTestByPub(String starttime, String endtime) {
        /*GameTestSearchCriteria searchCriteria = new GameTestSearchCriteria();
        searchCriteria.setPubCheck("on");
        searchCriteria.setTimeStart(starttime);
        searchCriteria.setTimeEnd(endtime);
        searchCriteria.setCtype(1);
        searchCriteria.addOrderBy(GameTestOrderBy.TIME_ASC).addOrderBy(GameTestOrderBy.POWER_DESC);
        
        return gameTestRemoteService.listSearch(searchCriteria);*/
        Map<String, String> map = new HashMap<String, String>();
        map.put("checkBeta", "on");
        map.put("timeStart", starttime);
        map.put("timeEnd", endtime);
        map.put("order1", "time");
        map.put("order1Type", "asc");
        map.put("order2", "weights");
        map.put("order2Type", "desc");
        return fahaoRemoteService.listSearchGameTestInfo(map);
    }

    @Override
    public List<GameTestInfo> getNoPubTest(String starttime, String endtime) {
        /*GameTestSearchCriteria searchCriteria = new GameTestSearchCriteria();
        searchCriteria.setPubCheck("");
        searchCriteria.setTimeStart(starttime);
        searchCriteria.setTimeEnd(endtime);
        searchCriteria.setCtype(1);
        searchCriteria.addOrderBy(GameTestOrderBy.TIME_ASC).addOrderBy(GameTestOrderBy.POWER_DESC);
        
        return gameTestRemoteService.listSearch(searchCriteria);*/
        Map<String, String> map = new HashMap<String, String>();
        map.put("checkBeta", "");
        map.put("timeStart", starttime);
        map.put("timeEnd", endtime);
        map.put("order1", "time");
        map.put("order1Type", "asc");
        map.put("order2", "weights");
        map.put("order2Type", "desc");
        return fahaoRemoteService.listSearchGameTestInfo(map);
    }

    @Override
    public List<GameTestInfo> getFreeGameInfo(String starttime, String endtime) {
        /*GameTestSearchCriteria searchCriteria = new GameTestSearchCriteria();
        searchCriteria.setFreeGame("on");
        searchCriteria.setTimeStart(starttime);
        searchCriteria.setTimeEnd(endtime);
        searchCriteria.setCtype(1);
        searchCriteria.addOrderBy(GameTestOrderBy.TIME_ASC).addOrderBy(GameTestOrderBy.POWER_DESC);
        
        return gameTestRemoteService.listSearch(searchCriteria);*/
        Map<String, String> map = new HashMap<String, String>();
        map.put("freeGame", "on");
        map.put("timeStart", starttime);
        map.put("timeEnd", endtime);
        map.put("order1", "time");
        map.put("order1Type", "asc");
        map.put("order2", "weights");
        map.put("order2Type", "desc");
        return fahaoRemoteService.listSearchGameTestInfo(map);
    }

    @Override
    public List<GameTestInfo> getHasPayGameInfo(String starttime, String endtime) {
        /*GameTestSearchCriteria searchCriteria = new GameTestSearchCriteria();
        searchCriteria.setHasPay("on");
        searchCriteria.setTimeStart(starttime);
        searchCriteria.setTimeEnd(endtime);
        searchCriteria.setCtype(1);
        searchCriteria.addOrderBy(GameTestOrderBy.TIME_ASC).addOrderBy(GameTestOrderBy.POWER_DESC);
        
        return gameTestRemoteService.listSearch(searchCriteria);*/
        Map<String, String> map = new HashMap<String, String>();
        map.put("hasPay", "on");
        map.put("timeStart", starttime);
        map.put("timeEnd", endtime);
        map.put("order1", "time");
        map.put("order1Type", "asc");
        map.put("order2", "weights");
        map.put("order2Type", "desc");
        return fahaoRemoteService.listSearchGameTestInfo(map);
    }

    @Override
    public List<GameTestInfo> getAbroadGameInfo(String starttime, String endtime) {
        /*GameTestSearchCriteria searchCriteria = new GameTestSearchCriteria();
        searchCriteria.setAbroad("on");
        searchCriteria.setTimeStart(starttime);
        searchCriteria.setTimeEnd(endtime);
        searchCriteria.setCtype(1);
        searchCriteria.addOrderBy(GameTestOrderBy.TIME_ASC).addOrderBy(GameTestOrderBy.POWER_DESC);
        
        return gameTestRemoteService.listSearch(searchCriteria);*/
        Map<String, String> map = new HashMap<String, String>();
        map.put("abroad", "on");
        map.put("timeStart", starttime);
        map.put("timeEnd", endtime);
        map.put("order1", "time");
        map.put("order1Type", "asc");
        map.put("order2", "weights");
        map.put("order2Type", "desc");
        return fahaoRemoteService.listSearchGameTestInfo(map);
    }

    @Override
    public List<GameTestInfo> getGameTestByState(String state) {
        /*GameTestSearchCriteria searchCriteria = new GameTestSearchCriteria();
        searchCriteria.setState(state);
        searchCriteria.setCtype(1);
        searchCriteria.addOrderBy(GameTestOrderBy.TIME_ASC).addOrderBy(GameTestOrderBy.POWER_DESC);
        
        return gameTestRemoteService.listSearch(searchCriteria);*/
        Map<String, String> map = new HashMap<String, String>();
        map.put("state", state);
        map.put("order1", "time");
        map.put("order1Type", "asc");
        map.put("order2", "weights");
        map.put("order2Type", "desc");
        return fahaoRemoteService.listSearchGameTestInfo(map);
    }

    // ----游戏测试表：gametestinfo相关 end----

    // ----文章投票表：simplevote相关 begin----
    @Override
    public int getAgreeCount(String voteid, String channelid) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public int getDisagreeCount(String voteid, String channelid) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public String getAgreeVotePrecent(String voteid, String channelid) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public String getDisagreeVotePrecent(String voteid, String channelid) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public int getNewVoteCount(String voteid, String channelid) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public List getVoteRecordByTime(String channelid, String starttime, String endtime, int size) {
        // TODO Auto-generated method stub
        return null;
    }

    // ----文章投票表：simplevote相关 end----

    // ----文章心情投票表: moodvote相关 begin----
    @Override
    public int getMoodVoteNum(String channelid, String voteid, int index) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public int getMoodVoteCount(String channelid, String voteid) {
        // TODO Auto-generated method stub
        return 0;
    }

    // ----文章心情投票表: moodvote相关 end----

    @Override
    public List newgameHotList(String type, int start, int len) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public String getGuildLv(int lv) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public String[] getGuildCooperateLv() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public int getGuildCount(int lv) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public List getGuildCooperatelist(int lv, int start, int len) {
        // TODO Auto-generated method stub
        return null;
    }

    // @Override
    // public String getTagUrl(String channelid, long tagid, long templateid) {
    // }
    //
    // @Override
    // public String getTagUrl(String channelid, long tagid) {
    // }

    @Override
    public String getTagUrl(String channelId, String tag) {
        if (StringUtil.hasOneEmpty(channelId, tag)) {
            return "";
        }
        ChannelInfo channelInfo = channelRemoteService.getById(channelId);
        TagInfo tagInfo = tagRemoteService.getByChannelIdAndName(channelId, tag);
        if (null == channelInfo || null == tagInfo)
            return "";
        return PathUtil.getTagOnlineUrl(channelInfo.getDomain(), tagInfo.getId());
    }

    @Override
    public String getTagUrl(String tag) {
        if (StringUtil.isEmpty(tag) || null == channelInfo)
            return "";
        TagInfo tagInfo = tagRemoteService.getByChannelIdAndName(channelInfo.getId(), tag);
        if (null == tagInfo)
            return "";
        return PathUtil.getTagOnlineUrl(channelInfo.getDomain(), tagInfo.getId());
    }

    // @Override
    // public String getPostCooperateUrl(String channelName, String articleId) {
    //
    // }
    //
    // @Override
    public String getTagRelatedUrl(String channelid, String tag, String cooperate) {

        if (StringUtil.hasOneEmpty(channelid, tag))
            return "";
        TagInfo tagInfo = tagRemoteService.getByChannelIdAndName(channelid, tag);
        if (null == tagInfo)
            return "";
        if (!StringUtil.isEmpty(cooperate))
            return "/" + channelid + "/tag/" + tagInfo.getId() + ".html";

        else
            return "/tag/" + tagInfo.getId() + ".html";

    }

    //
    // @Override
    // public String getTemplateRelatedUrl(String channelid, String
    // templatename, String cooperate) {
    // }
    //
    // @Override
    // public String getTemplateRelatedUrl(String channelid, String
    // templatename, String cooperate, String alias) {
    // }

    private String getId2Url(String id) {
        long long_id = 0L;
        try {
            long_id = Long.parseLong(id);
        } catch (Exception e) {
            logger.warn("id=" + id + "不合法");
            return "";
        }
        return PathUtil.getId2Url(long_id);
    }

    // 得到本频道文章绝对url
    @Override
    public String getUrl(String articleId) {
        if (null == channelInfo)
            return "";
        return channelInfo.getDomain() + getId2Url(articleId);
    }

    // 得到本频道文章相对url
    @Override
    public String getRelatedUrl(String articleId) {
        return getId2Url(articleId);
    }

    @Override
    public String getUrl(String channelName, String articleId) {
        ChannelInfo channel = getChannelInfoByName(channelName);
        if (null == channel)
            return "";
        return channel.getDomain() + getId2Url(articleId);
    }

    // 得到Web频道文章绝对url
    // @Override
    // public String getWebUrl(String articleId) {
    // return PathUtil.getWebChannelDomain() + getId2Url(articleId);
    // }

    // 得到该频道文章相对url
    @Override
    public String getRelatedUrl(String channelName, String articleId) {
        if (null == getChannelInfoByName(channelName))
            return "";
        return getId2Url(articleId);
    }

    // 得到某个tag的所有相关tag:父tag,兄弟tag,子tag
    @Override
    public String[] aboutTags(String tag) {
        if (StringUtil.isEmpty(tag))
            return null;

        String channelId = channelInfo.getId();
        TagInfo tagInfo = tagRemoteService.getByChannelIdAndName(channelId, tag);
        List<TagInfo> descendantList = tagRemoteService.getDescendantIncludeSelf(channelId, tagInfo.getParentName());

        List<String> tags = new ArrayList<String>();
        // 兄弟tag及其后代标签
        for (TagInfo tmp : descendantList) {
            tags.add(tmp.getName());
        }

        return tags.toArray(new String[tags.size()]);
    }

    // 根据realtags字符串，获得所有tag超链接
    @Override
    public String getTagsUrl(String realtags, String splits) {
        if (StringUtil.isEmpty(realtags))
            return "";
        StringBuffer sb = new StringBuffer();
        for (String tag : realtags.split(",")) {
            if (StringUtil.isEmpty(tag))
                continue;
            sb.append("<a href=\"" + getTagUrl(tag) + "\">" + tag + "</a>" + splits);
        }
        return sb.toString();
    }

    /**
     * 得到第一个tag的链接
     * @param realtags 使用逗号分隔的多个tag
     */
    @Override
    public String getFirstTagUrl(String realtags) {
        if (StringUtil.isEmpty(realtags))
            return "";
        if (realtags.startsWith(",")) { // 有可能是",A,B,C,D"的格式，那么先去除第一个逗号
            realtags = realtags.replaceFirst(",", "");
        }
        String[] tags = realtags.split(",");
        if (tags.length == 0)
            return "";
        StringBuffer sb = new StringBuffer();
        sb.append("<a href=\"" + getTagUrl(tags[0]) + "\">" + tags[0] + "</a>");
        return sb.toString();
    }

    // 得到某个tag的父tag
    @Override
    public String getParentTag(String tag) {
        TagInfo tagInfo = tagRemoteService.getByChannelIdAndName(channelInfo.getId(), tag);
        if (null != tagInfo)
            return tagInfo.getParentName();
        return null;
    }

    // ----通用评论接口begin----接入通用评论，以后调用通用评论的接口得到数据
    @Override
    public List getReplys(long threadid) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public List getReplys(long threadid, int start, int len) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public List getReplysByPtime(long threadid) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public List getAllReplys(long threadid, int start, int len) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public List getNotAccuseReplys(long threadid, int start, int len) {
        // TODO Auto-generated method stub
        return null;
    }

    // ----通用评论接口 end----

    // 获得数组长度
    @SuppressWarnings("rawtypes")
    @Override
    public int getLength(Object list) {

        if (null == list)
            return 0;
        if (list instanceof List) {
            return ((List) list).size();
        } else if (list instanceof Object[]) {
            return ((Object[]) list).length;
        }
        return 0;
    }

    // 减法----没有被调用
    @Override
    public int sub(int t, int s) {
        return t - s;
    }

    @Override
    public String[] splits_rs(String content, String regex) {
        if (StringUtil.isEmpty(content) || StringUtil.isEmpty(regex))
            return null;
        String[] s = content.split(StringUtil.escapeRegex(regex));
        return s;
    }

    // 获得多个频道指定tag中权重在指定数以上的文章("彩虹岛,重点,120{%}彩虹岛,重点,120"),参考旧发布器实现(实现有点扯淡)
    @Override
    public List<Article4TagListInfo> getChannelsTag(String s, int num) {

        if (StringUtil.isEmpty(s) || num < 1)
            return new ArrayList<Article4TagListInfo>();

        List<Article4TagListInfo> list = new ArrayList<Article4TagListInfo>(num);

        int count = 0;
        for (String msg : s.split("\\{\\%\\}")) {
            String[] channelName_tag_power = msg.split(",");
            if (channelName_tag_power.length != 3)
                continue;
            String channelId = getChannelIdByName(channelName_tag_power[0]);
            String tag = channelName_tag_power[1];
            String powerfrom = channelName_tag_power[2];
            List<Article4TagListInfo> articles = getCommonList(channelId, tag, Integer.parseInt(powerfrom), 255, null, 0, 1);
            if (null != articles && count < num) {
                list.add(articles.get(0));
                count++;
            } else if (count >= num) {
                break;
            }
        }

        for (; count < num; count++) {
            Article4TagListInfo a = new Article4TagListInfo();
            a.setId(0L);
            list.add(a);
        }
        return list;
    }

    /**
     * 获取发号数据
     * @param jsonParam
     * @return
     */
    @Override
    public Map<String, List<FahaoInfo>> getFahaoRank(String jsonParam) {
        try {
            FahaoRequest fr = JsonUtil.jsonString2JavaBean(FahaoRequest.class, jsonParam);
            return fahaoRemoteService.getFahaoRank(fr.getAction(), fr.getGameName());
        } catch (Exception e) {
            logger.warn("getFahaoRank fail!!获取发号排行失败!!jsonParam:" + jsonParam, e);
            return new HashMap<String, List<FahaoInfo>>();
        }
    }

    /**
     * 获取投票排行榜数据
     * @param jsonParam
     * @return
     */
    @Override
    public List<ArticleInfo> getVoteRankData(String channelId, String tag, int status, int type, int start, int size, String startDate, String endDate, String queryType) {
        // TODO Auto-generated method stub
        return null;
    }

    /**
     * 获取投票排行榜数据
     * @param jsonParam
     * @return
     * @throws Exception 
     */
    @Override
    public List<Article4TagListInfo> getVoteRankDataByArticle(String channelId, String cmsTag, int start, int size, String startDate, String endDate, String queryType) throws Exception{
        // statistics-->投票系统的tag,流量统计
        return getVoteRankDataByTag(channelId, cmsTag, "statistics", 1, 5, start, size, startDate, endDate, queryType, false);
    }

    /**
     * 根据发布器中的tag和投票相关的选项获取投票排行榜数据的接口，
     * @param jsonParam
     * @return
     * @throws Exception 
     */
    @Override
    public List<Article4TagListInfo> getVoteRankDataByTag(String channelId, String cmsTag, String voteTag, int status, int type, int start, int size, String startDate,
            String endDate, String queryType, boolean needDigest) throws Exception{

        // 返回的list
        List<Article4TagListInfo> resultList = new ArrayList<Article4TagListInfo>();

        if (StringUtil.hasOneEmpty(channelId, cmsTag, voteTag)) {
            logger.error("the [channelId|cmsTag|voteTag] parameter must be input!");
            return resultList;
        }
        // 1.得到cmsTag及其子孙tag
        List<TagInfo> tag_list = tagRemoteService.getDescendantIncludeSelf(channelId, cmsTag);
        // 2.查询3000条文章记录，根据tag集和channelId
        Article4TagListSearchCriteria searchCriteria = new Article4TagListSearchCriteria();
        searchCriteria.setChannelId(channelId);
        searchCriteria.setPageSize(3000);
        for (TagInfo tagInfo : tag_list) {
            searchCriteria.addTags(tagInfo.getName());
        }
        long interval = 90 * 24 * 60 * 60 * 1000L;
        long condition = 4 * 24 * 60 * 60 * 1000L + 1;
        String key = channelId + "_" + cmsTag + "_" + queryType;
        if (StringUtil.hasOneEmpty(startDate, endDate)) {
            searchCriteria.setPublishTimeEnd(new Date());
            searchCriteria.setPublishTimeStart(DateUtil.getBeforeTime(90 * 24 * 60));// 查询90天(3个月)前的
        } else {
            Date[] start_end = validateStr2Date(startDate, endDate);
            searchCriteria.setPublishTimeStart(start_end[0]);
            searchCriteria.setPublishTimeEnd(start_end[1]);
            interval = start_end[1].getTime() - start_end[0].getTime();
        }
        List<Article4TagListInfo> articleList = article4TagListRemoteService.listSearch(searchCriteria);
        
        if(null == articleList){
            articleList = resultList;
        }
        
        // 将文章放入map中
        Map<Long, Article4TagListInfo> map = new HashMap<Long, Article4TagListInfo>();
        for (Article4TagListInfo a : articleList) {
            map.put(a.getId(), a);
        }
        logger.info("发布器频道["+channelId+"]标签：'" + cmsTag + "'下查询出" + map.size() + "篇文章进行流量排行!");
        
        if(map.size() < size){
            if(interval > 0 && interval < condition){
                List<Article4TagListInfo> cacheList = (List<Article4TagListInfo>)cacheHolder.get(key);
                if(cacheList == null){
                    return resultList;
                }else if(cacheList.size() > size){
                    return cacheList.subList(0, size);
                }else{
                    return cacheList;
                }
            }else{
                throw new Exception("频道["+channelId+"]标签：'" + cmsTag + "'下文章不足!");
            }
            //return resultList;
        }
        

        // 3.整理向投票发请求的参数，并调用服务进行查询
        DuowanVoteSearchCriteria criteria = new DuowanVoteSearchCriteria();
        criteria.setChannelId(channelId);
        criteria.setTag(voteTag);// 投票系统的tag,statistics-->流量统计
        criteria.setStatus(status);
        criteria.setType(type);
        criteria.setStart(start);
        criteria.setSize(size);
        // 对于投票系统来说，这两个参数用于自定日期区间，目前已经不支持
        // criteria.setStartDate(startDate);
        // criteria.setEndDate(endDate);
        // queryType-->查询类型：有四种，按日，周，月，总数。分别是：day_statistic_article,week_statistic_article,month_statistic_article,total_statistic_article
        criteria.setQueryType(queryType);
        criteria.setArticleIds(getArticleIdsFromIdSet(map.keySet()));

        // 得到查询数据：articleId,votenum即每个ArticleSimpleInfo只有这两个属性有值
        LinkedHashMap<Long, Long> resultMap = duowanVoteRemoteService.getVoteRankDataByArticles(criteria);
        if (null == resultMap || resultMap.size() != size) {
            //logger.warn("排行榜返回的数排行数量是:" + resultList.size() + ",但请求的数量却是:" + size + ",数量不相等!channelid:" + channelId + ",cms tag:" + cmsTag);
            throw new Exception("排行数不足!channelid:" + channelId + ",cms tag:" + cmsTag);
        }

        for (Long articleId : resultMap.keySet()) {
            Article4TagListInfo a = map.get(articleId);
            a.setSum(resultMap.get(articleId));
            resultList.add(a);
        }
        
        //进行条件缓存
        if(interval > 0 && interval < condition){
            cacheHolder.put(key, resultList);
        }

        return resultList;
    }
    
    private String getArticleIdsFromIdSet(Set<Long> set) {
        StringBuffer sb = new StringBuffer();
        for (Long id : set) {
            sb.append(id).append(",");
        }
        String str = sb.toString();
        return str.length() > 1 ? str.substring(0, sb.length() - 1) : "";
    }

    private Date[] validateStr2Date(String startDate, String endDate) {
        Date startD = null;
        Date endD = null;
        boolean isvaledate = true;// startDate,endDate是否合法
        try {
            startD = DateUtil.parse(startDate, "yyyy-MM-dd");
            endD = DateUtil.parse(endDate, "yyyy-MM-dd");
            long tmp = 90 * 24 * 60 * 60 * 1000L;// 90天
            if (endD.getTime() - startD.getTime() > tmp)
                startD = new Date(endD.getTime() - tmp);
        } catch (ParseException e) {
            isvaledate = false;
            logger.warn("日期解析错误!", e);
        }
        if (isvaledate) {
            return new Date[] { startD, endD };
        } else {
            return new Date[] { DateUtil.getBeforeTime(90 * 24 * 60), new Date() };
        }
    }
    
    @Override
    public CommentInfo getVNumByAId(String channelId, String articleId) {
        
        ArticleInfo articleInfo = articleRemoteService.getByChannelIdAndArticleId(channelId, Long.parseLong(articleId));
        int count = comment3RemoteService.getCommentCount(articleInfo);
        CommentInfo commentInfo = new CommentInfo();
        commentInfo.setCount(count);
        return commentInfo;
    }
    
    @Override
    public List<Article4TagListInfo> getCommentRankDataByTag(String channelId, String cmsTags, int start, int size, String startDate, String endDate) {
        
        // 返回的list
        List<Article4TagListInfo> resultList = new ArrayList<Article4TagListInfo>();

        if (StringUtil.hasOneEmpty(channelId, cmsTags)) {
            logger.warn("the [channelId|cmsTags] parameter must be input!");
            return resultList;
        }
        
        ChannelInfo channel = channelRemoteService.getById(channelId);
        
        if(null == channel){
            logger.warn("发布器系统查找不到专区["+channelId+"],无法进行评论排行");
            return resultList;
        }
        String key = channelId + "_" + cmsTags;
        //TODO 1.考虑加入子孙tag
        // 2.查询3000条文章记录，根据tag集和channelId
        Article4TagListSearchCriteria searchCriteria = new Article4TagListSearchCriteria();
        searchCriteria.setChannelId(channelId);
        searchCriteria.setPageSize(2000);
        searchCriteria.addOrderBy(Article4TagListOrderBy.DAY_NUM_DESC);
        for (String tag : cmsTags.split(",")) {
            searchCriteria.addTags(tag);
        }
        if (StringUtil.hasOneEmpty(startDate, endDate)) {
            searchCriteria.setPublishTimeEnd(new Date());
            searchCriteria.setPublishTimeStart(DateUtil.getBeforeTime(90 * 24 * 60));// 查询90天(3个月)前的
        } else {
            Date[] start_end = validateStr2Date(startDate, endDate);
            searchCriteria.setPublishTimeStart(start_end[0]);
            searchCriteria.setPublishTimeEnd(start_end[1]);
        }
        List<Article4TagListInfo> articleList = article4TagListRemoteService.listSearch(searchCriteria);
        // 将文章放入map中
        MD5 md5 = new MD5();
        Map<String, Article4TagListInfo> map = new HashMap<String, Article4TagListInfo>();
        Set<String> uniqids = new HashSet<String>();
        for (Article4TagListInfo a : articleList) {
            String uniqid = md5.get(a.getUrlOnLine()).toLowerCase();
            uniqids.add(uniqid);
            map.put(uniqid, a);
        }
        //3.调用服务查询
        String domain = channel.getDomain().replace("http://", "");
        //查2倍数据，防止数据不足(接口有问题)
        LinkedHashMap<String, String> resultMap = comment3RemoteService.getMoreCommentCount(domain, uniqids, start + 2 * size);
        //若查询不到，从缓存中取
        if (null == resultMap || resultMap.isEmpty()){
            //return resultList;
            List<Article4TagListInfo> cacheList = (List<Article4TagListInfo>)cacheHolder.get(key);
            if(cacheList == null){
                return resultList;
            }else if(cacheList.size() > size){
                return cacheList.subList(0, size);
            }else{
                return cacheList;
            }
        }
            

        for (String uniqid : resultMap.keySet()) {
            Article4TagListInfo a = map.get(uniqid);
            if(StringUtil.isNumber(resultMap.get(uniqid)))
                a.setCommentCount(Integer.parseInt(resultMap.get(uniqid)));
            if(start > 0){
                start --;
            }else{
                if(size -- > 0){
                    resultList.add(a);
                }else{
                    break;
                }
            }
        }
        //进行缓存
        if("newgame".equals(channelId)){
            cacheHolder.put(key, resultList);
        }
        return resultList;
    }
    
    // 获得某篇文章的访问量，与投票系统交互
    @Override
    public int getVNum(String articleId, String channelId, String title, String url) {

        return duowanVoteRemoteService.getVoteNum(articleId, channelId, title, url);
    }

    @Override
    public List<GameTestInfo> getGameTestList(int startDay, int endDay, int ctype, boolean revers) {
        String starttime = DateUtil.format(DateUtil.getDate(startDay), DateUtil.defaultDatePatternStr);
        String endtime = DateUtil.format(DateUtil.getDate(endDay), DateUtil.defaultDatePatternStr);
        
        /*GameTestSearchCriteria searchCriteria = new GameTestSearchCriteria();
        searchCriteria.setPageSize(null);
        searchCriteria.setAbroadNot("on");
        searchCriteria.setCtype(ctype);
        searchCriteria.setTimeStart(starttime);
        searchCriteria.setTimeEnd(endtime);
        searchCriteria.addOrderBy(GameTestOrderBy.TIME_DESC).addOrderBy(GameTestOrderBy.POWER_DESC);
        List<GameTestInfo> list = gameTestRemoteService.listSearch(searchCriteria);*/
        
        Map<String, String> map = new HashMap<String, String>();
        map.put("abroadNot", "on");
        map.put("timeStart", starttime);
        map.put("timeEnd", endtime);
        map.put("order1", "time");
        map.put("order1Type", "desc");
        map.put("order2", "weights");
        map.put("order2Type", "desc");
        
        
        List<GameTestInfo> list = fahaoRemoteService.listSearchGameTestInfo(map);
        resetTime(list);
        if(revers){
            Collections.reverse(list);
        }
        return list;
    }
    
    private void resetTime(List<GameTestInfo> list){
        for (GameTestInfo g : list) {
            String time = DateUtil.format(g.getTime(), DateUtil.defaultDatePatternStr);
            if(time!=null){
                if(time.equals(DateUtil.format(DateUtil.getDate(0), DateUtil.defaultDatePatternStr))){
                    g.setTimeStr("今天");
                }else if(time.equals(DateUtil.format(DateUtil.getDate(1), DateUtil.defaultDatePatternStr))){
                    g.setTimeStr("明天");
                }else if(time.equals(DateUtil.format(DateUtil.getDate(2), DateUtil.defaultDatePatternStr))){
                    g.setTimeStr("后天");
                }else if(time.equals(DateUtil.format(DateUtil.getDate(-1), DateUtil.defaultDatePatternStr))){
                    g.setTimeStr("1天前");
                }else if(time.equals(DateUtil.format(DateUtil.getDate(-2), DateUtil.defaultDatePatternStr))){
                    g.setTimeStr("2天前");
                }else if(time.equals(DateUtil.format(DateUtil.getDate(-3), DateUtil.defaultDatePatternStr))){
                    g.setTimeStr("3天前");
                }else if(time.equals(DateUtil.format(DateUtil.getDate(-4), DateUtil.defaultDatePatternStr))){
                    g.setTimeStr("4天前");
                }else if(time.equals(DateUtil.format(DateUtil.getDate(-5), DateUtil.defaultDatePatternStr))){
                    g.setTimeStr("5天前");
                }else if(time.equals(DateUtil.format(DateUtil.getDate(-6), DateUtil.defaultDatePatternStr))){
                    g.setTimeStr("6天前");
                }else if(time.equals(DateUtil.format(DateUtil.getDate(-7), DateUtil.defaultDatePatternStr))){
                    g.setTimeStr("7天前");
                }
            }
        }
    }

    @Override
    public List<TujiInfo> getTujiList(String jsonStr) {
        TujiRequest tr = JsonUtil.jsonString2JavaBean(TujiRequest.class, jsonStr);
        try {
            return picLibRemoteService.getList(tr.getAlias(), tr.getNum(), tr.getPage(), tr.getSort(), tr.getTag());
        } catch (BaseCheckedException e) {
            logger.warn("获取图集数据失败!", e);
        }
        return new ArrayList<TujiInfo>();
    }

    @Override
    public void setChannelInfo(ChannelInfo channelInfo) {
        this.channelInfo = channelInfo;
    }

}
